package com.softstone.sng.server;

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;
import com.jme3.network.ConnectionListener;
import com.jme3.network.HostedConnection;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.JmeContext;
import com.softstone.sng.client.Main;
import com.softstone.sng.messages.ManualControlMessage;
import com.softstone.sng.messages.PlayerMessage;
import com.softstone.sng.messages.SetupMessages;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tomav
 */
public class ServerMain extends SimpleApplication implements ConnectionListener
{

  private com.jme3.network.Server server;
  private Map<Integer,Geometry> players = new HashMap<Integer, Geometry>();
  private Random random = new Random();

  public Server getServer()
  {
    return server;
  }

  public static void main(String[] args)
  {

    ServerMain app = new ServerMain();
    app.start(JmeContext.Type.Headless);
  }

  @Override
  public void simpleInitApp()
  {
    try
    {
      server = Network.createServer(Main.GAME_NAME, Main.GAME_VERSION, 6143, 6143);
      server.start();
    } catch (IOException ex)
    {
      Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, "Cannot start server: {0}", ex);
      return;
    }
    SetupMessages.register();
    server.addConnectionListener(this);
    server.addMessageListener(new MsgListener(), ManualControlMessage.class);
    new Thread(new ListeningThread()).start();
  }

  @Override
  public void destroy()
  {
    server.close();
    super.destroy();
  }

  public void connectionAdded(Server server, HostedConnection conn)
  {
    Geometry g = new Geometry(""+conn.getId(), new Box(Vector3f.ZERO, 1, 1, 1));
    g.setLocalTranslation(random.nextFloat()*10, random.nextFloat()*10, random.nextFloat()*10);
    players.put(conn.getId(), g);
    server.broadcast(new PlayerMessage(conn.getId(), true,g.getLocalTranslation()));
  }

  public void connectionRemoved(Server server, HostedConnection conn)
  {
    server.broadcast(new PlayerMessage(conn.getId(), false, null));
    players.remove(conn.getId());
  }

  private class ListeningThread implements Runnable
  {
    @Override
    public void run()
    {
      Boolean close = false;
      System.out.println("Type x to close server");
      Scanner in = new Scanner(System.in);
      while (!close)
      {
        String s = in.nextLine();
        if (s.equals("x"))
        {
          close = true;
        }
        else
        {
          System.out.println(ServerMain.this.getServer().getConnections().size());
          System.out.println(players.size());
          for(Geometry g : players.values())
            System.out.println(g.getLocalTranslation());
        }
      }
      ServerMain.this.stop();
    }
  }
}
